package com.shadow.study.test.study3;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.exec.*;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.time.Duration;

@Slf4j
public class AsyncExec {

    public static void main(String[] args) {
        log.info("async ping");
        // 构建命令行
        CommandLine commandLine = CommandLine.parse("ping 127.0.0.1");

        // 接收正常结果流
        ByteArrayOutputStream successStream = new ByteArrayOutputStream();
        // 接收异常结果流
        ByteArrayOutputStream errorStream = new ByteArrayOutputStream();

        // 构造默认执行器
        DefaultExecutor executor = DefaultExecutor.builder().get();
        // 设置超时时间
        ExecuteWatchdog watchdog = ExecuteWatchdog.builder().setTimeout(Duration.ofMillis(60 * 1000)).get();
        executor.setWatchdog(watchdog);
        // 创建流处理器，用于将命令的输出重定向到指定的流
        PumpStreamHandler streamHandler = new PumpStreamHandler(successStream, errorStream);
        executor.setStreamHandler(streamHandler);

        // 执行命令
        try {
            // 创建异步结果处理
            ExecuteResultHandler resultHandler = new ExecuteResultHandler() {
                @Override
                public void onProcessComplete(int exitValue) {
                    try {
                        String success = successStream.toString("GBK");
                        log.info("success: {}", success);
                    } catch (UnsupportedEncodingException e) {
                        log.error("处理命令执行失败后发生了异常", e);
                    }
                }

                @Override
                public void onProcessFailed(ExecuteException e) {
                    try {
                        String error = errorStream.toString("GBK");
                        log.info("error: {}", error);
                    } catch (UnsupportedEncodingException ex) {
                        log.error("处理命令执行失败后发生了异常", ex);
                    }
                }
            };
            log.info("execute start");
            executor.execute(commandLine, resultHandler);
            log.info("execute end");
            // 避免主线程退出导致程序退出
            Thread.currentThread().join();
        } catch (IOException e) {
            log.error("发生了异常", e);
        } catch (InterruptedException e) {
            log.error("发生了线程异常", e);
        }
    }
}
